package com.example.func.utils;

public class IdempotencyKeyUtil {


	/**
	 * 通用：基于任意关键字段集合和【默认日分桶+默认分隔符"|"+MD5】生成 requestId。
	 * 等价于：keyRaw = join(parts, "|") + "|" + yyyyMMdd；requestId = md5(keyRaw) 小写32位。
	 */
	public static String generateRequestId(java.util.Collection<?> keyParts) {
		return generateRequestId(keyParts, java.time.LocalDate.now());
	}

	/**
	 * 通用：基于任意关键字段集合和指定 LocalDate 分桶生成 requestId（MD5-32位小写）。
	 */
	public static String generateRequestId(java.util.Collection<?> keyParts, java.time.LocalDate dateBucket) {
		String bucket = (dateBucket == null ? java.time.LocalDate.now() : dateBucket).toString().replace("-", "");
		String keyRaw = buildKeyRaw("|", keyParts, bucket);
		return md5HexLower32(keyRaw);
	}


	/**
	 * 构造原始 key 串：join(parts, delimiter) + （可选）+ delimiter + bucket。
	 */
	private static String buildKeyRaw(String delimiter, java.util.Collection<?> keyParts, String bucket) {
		String sep = delimiter == null ? "|" : delimiter;
		java.util.StringJoiner joiner = new java.util.StringJoiner(sep);
		if (keyParts != null) {
			for (Object part : keyParts) {
				joiner.add(part == null ? "" : part.toString().trim());
			}
		}
		String base = joiner.toString();
		if (bucket != null && !bucket.isEmpty()) {
			return base.isEmpty() ? bucket : base + sep + bucket;
		}
		return base;
	}

	/**
	 * 计算字符串的 MD5 十六进制（小写，32 位）。
	 */
	private static String md5HexLower32(String input) {
		try {
			java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
			byte[] digest = md.digest(input.getBytes(java.nio.charset.StandardCharsets.UTF_8));
			StringBuilder sb = new StringBuilder(digest.length * 2);
			for (byte b : digest) {
				String hex = Integer.toHexString((b & 0xFF) | 0x100).substring(1);
				sb.append(hex);
			}
			return sb.toString(); // 32 位小写十六进制
		} catch (java.security.NoSuchAlgorithmException e) {
			// 按理 MD5 总是存在；若异常，退化为 input 的哈希码字符串以避免中断
			return Integer.toHexString(input.hashCode());
		}
	}

}
